package XML;

import Arbori.*;
import java.io.*;
import java.util.ArrayList;
import Operatori.*;
import FunctiiTrigo.*;
import FunctiiElementare.*;

public class LoadXML {
	protected ArboreFunctional a;
	protected Nod n;
	protected FileReader fstream;
	protected BufferedReader in;
	protected ArrayList<Nod> listaN;
	protected ArrayList<Integer> listaIndex;
	protected int dim;

	public LoadXML(String fisier) throws IOException {
		fstream = new FileReader(fisier);
		in = new BufferedReader(fstream);
		listaN = new ArrayList<Nod>(100);
		listaIndex = new ArrayList<Integer>(100);
		read();
		creareArbore();
		in.close();
		this.a = new ArboreFunctional((Nod) listaN.get(0));
	}

	public ArboreFunctional getArbore() {
		return this.a;
	}

	public void read() throws IOException {
		String sir = in.readLine();
		int index = 0, i = -1;
		double valoare = 0;
		sir = in.readLine();

		while (sir != null) {
			if (sir.indexOf("/") == -1) {
				i++;
				index = getNivel(sir);
				if (sir.indexOf("Constanta") != -1)
					valoare = getValoare(sir);
				sir = prelucrareSir(sir);
				if (sir.equals("Plus"))
					n = new Plus();
				else if (sir.equals("Minus"))
					n = new Minus();
				else if (sir.equals("Produs"))
					n = new Produs();
				else if (sir.equals("Putere"))
					n = new Putere();
				else if (sir.equals("Cat"))
					n = new Cat();
				else if (sir.equals("Sin"))
					n = new Sin();
				else if (sir.equals("Cos"))
					n = new Cos();
				else if (sir.equals("Necunoscuta"))
					n = new Necunoscuta();
				else if (sir.equals("Constanta"))
					n = new Constanta(valoare);
				listaN.add(n);
				listaIndex.add(index);
			} 
			sir = in.readLine();
		}
		dim = i;
		System.out.println();
		System.out.println();
	}

	public String prelucrareSir(String sir) throws IOException {
		sir = sir.trim();
		int index = 0, index1;
		if ((index1 = sir.indexOf(' ')) != -1)
			index = index1;
		else
			index = sir.indexOf('>');
		String sir2 = sir.substring(1, index);
		return sir2;
	}

	public int getNivel(String sir) throws IOException {
		sir = sir.trim();
		int index = 0, index1, index2;
		if ((index1 = sir.indexOf("id=\"")) != -1)
			index = index1;
		else
			System.out.println("Eroare: Format xml gresit");
		index2 = sir.substring(index + 4).indexOf('\"');
		sir = sir.substring(index + 4, index + 4 + index2);
		return Integer.parseInt(sir);
	}

	public double getValoare(String sir) {
		sir = sir.trim();
		int index = 0, index1, index2;
		if ((index1 = sir.indexOf("val=\"")) != -1)
			index = index1;
		else
			System.out.println("Eroare: Format xml gresit");
		index2 = sir.substring(index + 5).indexOf('\"');
		sir = sir.substring(index + 5, index + 5 + index2);
		return Double.parseDouble(sir);
	}

	public void creareArbore() {
		int nivel, j, nivel2, nivel1;
		for (int i = 0; i <= dim; i++) {
			nivel = listaIndex.get(i);
			nivel1 = listaIndex.get(i);
			if (!listaN.get(i).toString().contains("Constanta")
					&& !listaN.get(i).toString().contains("Necunoscuta")) {
				for (j = i; j < dim && (nivel2 = listaIndex.get(j)) >= nivel1; j++) {
					if (listaIndex.get(j) == nivel1 + 1) {
						if (listaN.get(i).getFStang() == null) {
							String nume = listaN.get(j).toString();
							if (nume.contains("Plus") || nume.contains("Minus")
									|| nume.contains("Produs")
									|| nume.contains("Cat")
									|| nume.contains("Putere")
									|| nume.contains("Constanta")
									|| nume.contains("Necunoscuta")
									|| nume.contains("Cos")
									|| nume.contains("Sin")
									|| nume.contains("Tg")
									|| nume.contains("Ctg")
									|| nume.contains("Log")
									|| nume.contains("Ln")
									|| nume.contains("Sqrt")
									|| nume.contains("Exp"))
								listaN.get(i).setFStang(listaN.get(j));
							else
								System.out.println("Eroare la stanga: "
										+ listaN.get(i).getClass().getName());
						} else {
							String nume = listaN.get(j).toString();
							if (nume.contains("Plus") || nume.contains("Minus")
									|| nume.contains("Produs")
									|| nume.contains("Cat")
									|| nume.contains("Putere")
									|| nume.contains("Constanta")
									|| nume.contains("Necunoscuta")
									|| nume.contains("Cos")
									|| nume.contains("Sin")
									|| nume.contains("Tg")
									|| nume.contains("Ctg")
									|| nume.contains("Log")
									|| nume.contains("Ln")
									|| nume.contains("Sqrt")
									|| nume.contains("Exp"))
								listaN.get(i).setFStang(listaN.get(j));
							else
								System.out.println("Eroare la dreapta: "
										+ listaN.get(i).getClass().getName());
						}
					}
					nivel1 = nivel2;
				}
				if (listaIndex.get(j) == nivel + 1) {
					if (listaN.get(i).getFStang() == null) {
						String nume = listaN.get(j).toString();
						if (nume.contains("Plus") || nume.contains("Minus")
								|| nume.contains("Produs")
								|| nume.contains("Cat")
								|| nume.contains("Putere")
								|| nume.contains("Constanta")
								|| nume.contains("Necunoscuta")
								|| nume.contains("Cos") || nume.contains("Sin")
								|| nume.contains("Tg") || nume.contains("Ctg")
								|| nume.contains("Log") || nume.contains("Ln")
								|| nume.contains("Sqrt")
								|| nume.contains("Exp"))
							listaN.get(i).setFStang(listaN.get(j));
						else
							System.out.println("Eroare la stanga: "
									+ listaN.get(i).getClass().getName());
					} else {
						String nume = listaN.get(j).toString();
						if (nume.contains("Plus") || nume.contains("Minus")
								|| nume.contains("Produs")
								|| nume.contains("Cat")
								|| nume.contains("Putere")
								|| nume.contains("Constanta")
								|| nume.contains("Necunoscuta")
								|| nume.contains("Cos") || nume.contains("Sin")
								|| nume.contains("Tg") || nume.contains("Ctg")
								|| nume.contains("Log") || nume.contains("Ln")
								|| nume.contains("Sqrt")
								|| nume.contains("Exp"))
							listaN.get(i).setFStang(listaN.get(j));
						else
							System.out.println("Eroare la dreapta: "
									+ listaN.get(i).getClass().getName());
					}
				}
			}
		}
	}
}
